package org.dizena.common.trace.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import org.dizena.common.base.enums.EnumHeaderKey;
import org.dizena.common.base.struct.TransmittableThreadLocalMap;
import org.dizena.common.utils.ReqUtil;
import org.dizena.common.wapper.RequestWrapper;
import org.slf4j.MDC;

import java.io.IOException;
import java.util.Map;
import java.util.UUID;

public class TraceFilterImpl implements Filter {

    private String service;

    public TraceFilterImpl(String service) {
        this.service = service;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        Map<String, String> header = ReqUtil.getHeaderMap(request);

        //check trace
        if (!header.containsKey(EnumHeaderKey.TRACE_ID.getKey())) {
            String reqId = UUID.randomUUID().toString().toLowerCase().replaceAll("-", "");
            header.put(EnumHeaderKey.TRACE_ID.getKey(), reqId);
            MDC.put(EnumHeaderKey.TRACE_ID.getKey(), reqId);
        } else {
            MDC.put(EnumHeaderKey.TRACE_ID.getKey(), header.get(EnumHeaderKey.TRACE_ID.getKey()));
        }

        if (!header.containsKey(EnumHeaderKey.REQUEST_IP.getKey())) {
            header.put(EnumHeaderKey.REQUEST_IP.getKey(), ReqUtil.getRequestIP(request));
        }

        //log.info("{} filter traceId {}", service, header.get(EnumHeaderKey.TRACE_ID.getKey()));
        // wrapper
        RequestWrapper wrapper = new RequestWrapper(request);
        for (Map.Entry<String, String> e : header.entrySet()) {
            wrapper.addHeader(e.getKey(), e.getValue());
            TransmittableThreadLocalMap.set(e.getKey(), e.getValue());
        }
        filterChain.doFilter(wrapper, servletResponse);
        //end
    }

}
